package com.accp.ssmoa.controller;

import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.accp.ssmoa.pojo.Menu;
import com.accp.ssmoa.pojo.User;
import com.accp.ssmoa.service.ShiroService;
import com.accp.ssmoa.util.VerifyCodeUtils;

@Controller
@Scope("prototype")
@RequestMapping("/shiro")
public class ShiroController {

	private static final transient Logger log = LoggerFactory.getLogger(ShiroController.class);

	@Resource
	private ShiroService shiroService;

	// 初始化登录页面
	@RequestMapping("/login")
	public String login() {

		return "login";

	}

	// 初始化首页
	@RequestMapping("/home")
	public String home(HttpServletRequest request, HttpSession session) {

		// 遍历出菜单项
		List<Menu> menus = shiroService.getAllMenus();

		request.setAttribute("mlist", menus);

		return "home/index";

	}

	// 登录操作
	@RequestMapping("/doLogin")
	public String doLogin(@ModelAttribute("User") User user, HttpServletRequest request, HttpSession session,
			HttpServletResponse response) {

		String eorr = null;// 错误信息

		// 验证码
		if (!session.getAttribute("veryCode").equals(request.getParameter("captcha"))) {
			eorr = "验证码输入错误";
			request.setAttribute("eorr", eorr);
			return "login";
		}

		/* 获取当前的Subject 调用SecurityUtils.getSubject()方法 */
		Subject currentUser = SecurityUtils.getSubject();

		/* 测试当前的用户是否已经被认证，即是否已经登录，调用Subject的isAuthenticated()方法 */
		if (!currentUser.isAuthenticated()) {
			// 把用户名和密码封装为UsernamePasswordToken对象
			UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());

			String rememberMe = request.getParameter("rememberMe");

			if (rememberMe != null) {
				// RememberMe 记住我
				token.setRememberMe(true);
			} else {
				token.setRememberMe(false);
			}

			try {
				// 执行登陆，调用Subject的login()方法
				currentUser.login(token);

			}
			// 若没有指定的账号，则shiro将会抛出 UnknownAccountException异常
			catch (UnknownAccountException uae) {
				log.info("There is no user with username of " + token.getPrincipal());
				eorr = "用户名不存在";

			}
			// 若账号存在，但密码不匹配，则shiro将会抛出 IncorrectCredentialsException异常
			catch (IncorrectCredentialsException ice) {
				log.info("Password for account " + token.getPrincipal() + " was incorrect!");
				eorr = "密码不匹配";
			}
			// 若用户被锁定，则shiro将会抛出 LockedAccountException 异常
			catch (LockedAccountException lae) {
				log.info("The account for username " + token.getPrincipal() + " is locked.  "
						+ "Please contact your administrator to unlock it.");
				eorr = "此账户已锁定，不可用";
			}
			// ... catch more exceptions here (maybe custom ones specific to your
			// application?
			// 所有认证时异常的父类
			catch (AuthenticationException ae) {
				log.info("抛出了终极异常：" + ae.getMessage());
				eorr = "未知异常";
			}
		}

		if (eorr == null) {

			session.setAttribute("user", user);

			return "redirect:/shiro/home";

		}

		// 将要显示在页面的异常放进request作用域中
		request.setAttribute("eorr", eorr);
		return "login";

	}

	// 验证码
	@RequestMapping("/random")
	public void authImage(HttpServletRequest request, HttpServletResponse response, HttpSession session)
			throws Exception {

		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);
		response.setContentType("image/jpeg");

		// 获取随机生成的验证码，参数为验证码位数
		String verifyCode = VerifyCodeUtils.generateVerifyCode(4);

		// 将验证码存进session，用于判断用户输入的验证码是否一致
		session.removeAttribute("veryCode");
		session.setAttribute("veryCode", verifyCode);

		// 获取随机生成的图片，并将验证码放到图片中
		int w = 100, h = 30;
		VerifyCodeUtils.outputImage(w, h, response.getOutputStream(), verifyCode);

	}

}
